package com.bx.implatform.portal.interceptor;

import com.bx.implatform.portal.utils.SignatureUtils;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

import java.io.IOException;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

public class PortalHeaderInterceptor implements ClientHttpRequestInterceptor {


    private final String appKey;
    private final String secretKey;
    private final String key43;

    public PortalHeaderInterceptor(String appKey, String secretKey, String key43) {
        this.appKey = appKey;
        this.secretKey = secretKey;
        this.key43 = key43;
    }

    @Override
    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        String url = request.getURI().toString();
        System.out.println("portal拦截器拦截: " + url); // 打印URL（调试用）
        // 1. 获取当前时间戳
        long timestamp = Instant.now().getEpochSecond();
        // 2. 提取请求参数（GET：从URL；POST：从Body）
        Map<String, String> params = extractParams(request, body);
        // 3. 添加固定参数
        params.put("appKey", appKey);
        params.put("timestamp", String.valueOf(timestamp));
        // 4. 计算签名
        String signature = null;
        try {
            signature = SignatureUtils.generateSign(params, secretKey, key43);
        } catch (Exception e) {
            throw new RuntimeException("生成签名失败!");
        }
        // 5. 添加请求头
        HttpHeaders headers = request.getHeaders();
        headers.add("appKey", appKey);
        headers.add("signature", signature);
        headers.add("timestamp", String.valueOf(timestamp));

        return execution.execute(request, body);
    }


    /**
     * 从HTTP请求中提取参数（兼容URL参数、JSON Body和表单数据）
     *
     * @param request HTTP请求对象
     * @param body    请求体字节数组
     * @return 参数键值对Map（保持JSON原始格式）
     */
    public static Map<String, String> extractParams(HttpRequest request, byte[] body) {
        Map<String, String> params = new LinkedHashMap<>(); // 使用LinkedHashMap保持插入顺序

        try {
            // 1. 解析URL查询参数（保持原始编码）
            UriComponents uriComponents = UriComponentsBuilder.fromUriString(request.getURI().toString()).build();
            uriComponents.getQueryParams().forEach((key, values) -> {
                if (!values.isEmpty()) {
                    params.put(key, values.get(0)); // 直接取原始值，不自动解码
                }
            });

            // 2. 处理请求体（如果存在）
            if (body != null && body.length > 0 && request.getHeaders().getContentType() != null) {
                String contentType = request.getHeaders().getContentType().toString();
                String bodyStr = new String(body, StandardCharsets.UTF_8);

                if (contentType.contains("application/json")) {
                    // JSON请求体：解析为Map但保持原始字符串值
                    ObjectMapper mapper = new ObjectMapper();
                    JsonNode rootNode = mapper.readTree(bodyStr);
                    rootNode.fields().forEachRemaining(entry -> {
                        String value = entry.getValue().isValueNode() ?
                                entry.getValue().asText() :
                                entry.getValue().toString();
                        params.put(entry.getKey(), value);
                    });
                } else if (contentType.contains("x-www-form-urlencoded")) {
                    // 表单数据：智能识别JSON子段
                    Arrays.stream(bodyStr.split("&"))
                            .map(pair -> pair.split("=", 2)) // 只分割第一个=号
                            .filter(pair -> pair.length == 2)
                            .forEach(pair -> {
                                String key = pair[0];
                                String value = pair[1];

                                // 检测是否为JSON结构（简单判断开头结尾）
                                boolean isJson = (value.startsWith("{") && value.endsWith("}")) ||
                                        (value.startsWith("[") && value.endsWith("]"));

                                // 仅对非JSON值进行URL解码
                                params.put(key, isJson ? value : URLDecoder.decode(value, StandardCharsets.UTF_8));
                            });
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("解析请求参数失败: " + e.getMessage(), e);
        }

        return params;
    }
}